Skip to content

fix(agent_execution): resolve ActiveTask 'destroyed but pending' warning during teardown#1122

Open
arunmm8335 wants to merge 4 commits into
a2aproject:mainfrom
arunmm8335:fix/issue-1121
Open

fix(agent_execution): resolve ActiveTask 'destroyed but pending' warning during teardown#1122
arunmm8335 wants to merge 4 commits into
a2aproject:mainfrom
arunmm8335:fix/issue-1121

Conversation

@arunmm8335

Copy link
Copy Markdown

Fixes #1121. This PR resolves the issue where ActiveTask would throw an asyncio warning when being garbage collected, by ensuring the _producer_task is properly awaited during the _run_consumer teardown path, allowing queues to properly close without leaving dangling pending background tasks.

@arunmm8335 arunmm8335 requested a review from a team as a code owner July 4, 2026 10:52

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the _run_consumer method in active_task.py to await the _producer_task if it is not yet completed during shutdown. The review feedback correctly identifies that asyncio.CancelledError inherits from BaseException rather than Exception in Python 3.8+, meaning a cancellation error would propagate and bypass critical cleanup steps like decrementing the reference count. A code suggestion is provided to explicitly catch and handle asyncio.CancelledError.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +579 to +582
try:
await self._producer_task
except Exception as e:
logger.debug('Consumer[%s]: Awaited producer_task raised %r', self._task_id, e)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In Python 3.8+, asyncio.CancelledError inherits from BaseException rather than Exception. Since _producer_task is cancelled during task cancellation (e.g., via self._producer_task.cancel()), awaiting it here will raise asyncio.CancelledError.

Because the except Exception block does not catch BaseException, this error will propagate out of the finally block, preventing the remaining cleanup code (decrementing _reference_count and calling _maybe_cleanup()) from executing. This can lead to resource leaks and tasks not being properly cleaned up.

To fix this, explicitly catch asyncio.CancelledError and handle or ignore it.

Suggested change
try:
await self._producer_task
except Exception as e:
logger.debug('Consumer[%s]: Awaited producer_task raised %r', self._task_id, e)
try:
await self._producer_task
except asyncio.CancelledError:
pass
except Exception as e:
logger.debug('Consumer[%s]: Awaited producer_task raised %r', self._task_id, e)

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

🧪 Code Coverage (vs main)

⬇️ Download Full Report

Base PR Delta
src/a2a/server/agent_execution/active_task.py 95.92% 95.48% 🔴 -0.45%
Total 92.99% 92.97% 🔴 -0.02%

Generated by coverage-comment.yml

@arunmm8335 arunmm8335 changed the title Fix: ActiveTask 'Task was destroyed but it is pending!' warning during teardown fix(agent_execution): resolve ActiveTask 'destroyed but pending' warning during teardown Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ActiveTask producer task GC'd while pending — 'Task was destroyed but it is pending!' at turn boundaries

1 participant